#coding=utf-8

from collections import OrderedDict
from cart.models import *
from django.db.models import F
# 数据库的购物车管理类和session的购物车管理类的基类,基类中要有他们两个都有的四个行为方法,这些方法也相当于是一些接口:
class CartManager(object):
    # 添加到购物车
    def add(self,goodsid,colorid,sizeid,count,*args,**kwargs):
        '''添加商品，如果商品已经存在就更新商品的数量(self.update())，否则直接放到购物车'''
        pass
    # 删除购物车中的商品
    def delete(self,goodsid,colorid,sizeid,*args,**kwargs):
        '''删除一个购物项'''
        pass
    # 修改购物车中的商品
    def update(self,goodsid,colorid,sizeid,count,step,*args,**kwargs):
        '''更新购物项的数据,添加减少购物项数据'''
        pass
    # 拿到购物车当中的所有商品
    def queryAll(self,*args,**kwargs):
        ''':return CartItem  多个购物项'''
        pass

#当前用户未登录时候使用的类,session的购物车管理类,这个类里除了要有一个初始化方法和一个内置方法外,还要有它父类里的那四个方法
class SessionCartManager(CartManager):

    cart_name = 'cart'
    def __init__(self,session):
        self.session = session
        if self.cart_name not in self.session:
            # 创建一个有序的字典,用于临时存放要添加到购物车的商品
            self.session[self.cart_name] = OrderedDict()

    # 将商品id,颜色id,尺寸id进行拼接
    def __get_key(self,goodsid,colorid,sizeid):
        return goodsid+','+colorid+','+sizeid



    def add(self,goodsid,colorid,sizeid,count,*args,**kwargs):
        #获取购物项的唯一标示
        key = self.__get_key(goodsid,colorid,sizeid)

        # 判断当前这件商品是否存在于session字典中,如果存在就做一个更新操作,如果不存在就添加进去
        if key in self.session[self.cart_name]:
            self.update(goodsid,colorid,sizeid,count,*args,**kwargs)
        else:
            self.session[self.cart_name][key] = CartItem(goodsid=goodsid,colorid=colorid,sizeid=sizeid,count=count)
            pass



    # 购物车中的商品删除操作
    def delete(self,goodsid,colorid,sizeid,*args,**kwargs):
        key = self.__get_key(goodsid,colorid,sizeid)
        if key in self.session[self.cart_name]:
            del self.session[self.cart_name][key]

    # 购物车中的商品更新操作
    def update(self,goodsid,colorid,sizeid,step,*args,**kwargs):
        # 先获取购物项唯一标识
        key = self.__get_key(goodsid,colorid,sizeid)
        # 通过标识判断是否存在于session中,如果存在那就取出来然后将该商品购买数量进行一个增加操作
        if key in self.session[self.cart_name]:
            cartitem = self.session[self.cart_name][key]
            cartitem.count = int(str(cartitem.count))+int(step)

        # 如果不存在,那么此操作就会报错
        else:
            raise Exception('SessionManager中的update出错了')


    # 对session中的商品进行一个遍历,返回一个列表
    def queryAll(self,*args,**kwargs):
        return self.session[self.cart_name].values()

    # 此方法是要将session中缓存的购物项迁移到数据库中
    def migrateSession2DB(self):
        if 'user' in self.session:
            # 从session中获取当前用户
            user = User.objects.get(account=self.session.get('user'))
            # 然后从数据库中遍历判断刚才从session中查到的每个商品,如果数据库中的某个商品不存在session中那么就把当前用户添加到session中的该商品上去
            for cartitem in self.queryAll():
                if CartItem.objects.filter(goodsid=cartitem.goodsid,colorid=cartitem.colorid,sizeid=cartitem.sizeid).count()==0:
                    cartitem.user = user
                    cartitem.save()
                # 如果存在于数据库中那么就进行一个增加商品数量的操作
                else:
                    item = CartItem.objects.get(goodsid=cartitem.goodsid,colorid=cartitem.colorid,sizeid=cartitem.sizeid)
                    item.count = int(item.count)+int(cartitem.count)
                    item.save()
            # 然后吧已经迁移到数据库的这项商品从session中删除
            del self.session[self.cart_name]

#用户已登录后要使用的类,数据库管理类,里面除了初始化方法和一些增加删除更新的方法还有两个获取当前用户下的所有已购物商品,和某个已购物的商品
class DBCartManger(CartManager):
    def __init__(self,user):
        self.user = user

    def add(self,goodsid,colorid,sizeid,count,*args,**kwargs):


        if self.user.cartitem_set.filter(goodsid=goodsid,colorid=colorid,sizeid=sizeid).count()==1:
            self.update(goodsid,colorid,sizeid,count,*args,**kwargs)
        else:
            CartItem.objects.create(goodsid=goodsid,colorid=colorid,sizeid=sizeid,count=count,user=self.user)



    def delete(self,goodsid,colorid,sizeid,*args,**kwargs):
        self.user.cartitem_set.filter(goodsid=goodsid,colorid=colorid,sizeid=sizeid).delete()


    def update(self,goodsid,colorid,sizeid,step,*args,**kwargs):
        self.user.cartitem_set.filter(goodsid=goodsid,colorid=colorid,sizeid=sizeid).update(count=F('count')+int(step))

    # 获取当前用户的所有已购物商品
    def queryAll(self,*args,**kwargs):

        return self.user.cartitem_set.order_by('id').filter(isdelete=False).all()

    #获取当前用户下的某个已购物的商品
    def get_cartitems(self,goodsid,sizeid,colorid,*args,**kwargs):
        return self.user.cartitem_set.get(goodsid=goodsid,sizeid=sizeid,colorid=colorid)



# 工厂方法
#根据当前用户是否登录返回相应的CartManger对象
def getCartManger(request):
    if request.session.get('user'):
        #当前用户已登录
        user = User.objects.get(account=request.session.get('user'))
        return DBCartManger(user)
    return SessionCartManager(request.session)